package simtester.server



import java.text.DateFormat;
import java.text.SimpleDateFormat

import grails.test.mixin.*
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
 */
@TestFor(QueryController)
@Mock([User,TestCase,TestRun,ResultEntry,Team])
class QueryControllerTests {
    static testusername = 'testuser'
    static testcasename = 'tc1'
    static testcasescript = 'some script'
    static testcase
    static DateFormat dateFormat = new SimpleDateFormat('MM/dd/yyyy HH:mm:ss.SSS')
    
    @Before
    void setUp() {
        def u = new User(username: 'testuser', password: 'pass')
        def team = new Team(name: 'svt')
        team.addToUsers(u)
        
        testcase = new TestCase(name: 'tc1', owner: u, script: 'some script')
        team.addToTestcases(testcase)
        assert team.save()
    }

    @Test
    void queryResponseTime() {
        def tr = new TestRun(testcase: testcase, status: 'running')
        tr.save()
        
        def setupdata = [
            [resp: 20,   time: dateFormat.parse('01/21/2012 15:11:23.159').time],
            [resp: 40,   time: dateFormat.parse('01/21/2012 15:11:23.164').time],
            [resp: 70,   time: dateFormat.parse('01/21/2012 15:11:23.170').time],
            [resp: null, time: dateFormat.parse('01/21/2012 15:11:23.180').time]
        ]
        
        setupdata.each {
            new ResultEntry(testrun: tr, timestamp: new Date(it.time), level: 'INFO', response: it.resp, type: 'GET', user: 1, iteration: 2, entry: 'http://www.google.com/ content-type:text/html').save()
        }
        
        def expected = setupdata[0..2]
        
        request.method = 'GET'
        params.id  = tr.id.toString()
        
        controller.responsetime()

        assert response.json.responses == expected
    }
    
    @Test
    void queryResponseTimeWithMin() {
        def tr = new TestRun(testcase: testcase, status: 'running')
        tr.save()
        
        def setupdata = [
            [resp: 20,   time: dateFormat.parse('01/21/2012 15:11:23.159').time],
            [resp: 40,   time: dateFormat.parse('01/21/2012 15:11:23.164').time],
            [resp: 70,   time: dateFormat.parse('01/21/2012 15:11:23.170').time],
            [resp: null, time: dateFormat.parse('01/21/2012 15:11:23.180').time]
        ]
        
        setupdata.each {
            new ResultEntry(testrun: tr, timestamp: new Date(it.time), level: 'INFO', response: it.resp, type: 'GET', user: 1, iteration: 2, entry: 'http://www.google.com/ content-type:text/html').save()
        }
        
        def expected = setupdata[1..2]
        
        request.method = 'GET'
        params.id  = tr.id.toString()
        params.min = setupdata[1].time - 1
        
        controller.responsetime()

        assert response.json.responses == expected
    }
    
    @Test
    void queryOutputs() {
        def tr = new TestRun(testcase: testcase, status: 'running')
        tr.save()
        
        def testUser = 2
        def testIter = 3
        long time = System.currentTimeMillis()
        def testId = time+2
        def setupdata = [
            [time: time,   iteration: 2,      , entry: 'entry 1'],
            [time: time+1, iteration: testIter, entry: 'entry 2'],
            [time: time+2, iteration: testIter, entry: 'entry 3'],
            [time: time+3, iteration: 4,      , entry: 'entry 4']
        ]
        
        setupdata.each {
            new ResultEntry(testrun: tr, timestamp: new Date(it.time), level: 'INFO', response: 20, type: 'GET', user: testUser, iteration: it.iteration, entry: it.entry).save()
        }
        
        def expected = [:]
        expected.outputs = setupdata[1..2].collect { [it.entry] }
        expected.highestId = testId
        
        request.method = 'GET'
        params.id   = tr.id.toString()
        params.user = testUser.toString()
        params.iter = testIter.toString()
        params.min  = (time+1).toString()
        
        controller.outputs()
        
        def results = response.json
        assert results.outputs.size() == 2
        assert results.highestId == expected.highestId
        results.outputs.eachWithIndex { x, i ->
            assert x =~ /INFO: GET ${expected.outputs[i]}/
        }
    }
}
